<?php

namespace App\Library\Service;

use App\Library\Logic\OperateLogLogic;
use App\Library\Logic\ShopProductLogic;
use App\Library\Logic\ShopProductSpecsLogic;
use App\Library\Requests\Base\ShopProductSpecNumberRequest;
use App\Library\Requests\ShopProductSpec\ShopProductSpecAddRequest;
use App\Library\Requests\ShopProductSpec\ShopProductSpecEditPriceRequest;
use App\Library\Requests\ShopProductSpec\ShopProductSpecEditRequest;
use App\Library\Requests\ShopProductSpec\ShopProductSpecEditStockRequest;
use App\Library\Requests\ShopProductSpec\ShopProductSpecPageRequest;
use Illuminate\Http\JsonResponse;

class ShopProductSpecService extends BaseService
{
    /**
     * @param ShopProductSpecsLogic $logic
     */
    public function __construct(ShopProductSpecsLogic $logic)
    {
        $this->logic = $logic;
    }

    /**
     * 分页
     * @param ShopProductSpecPageRequest $request
     * @return JsonResponse
     */
    public function paging(ShopProductSpecPageRequest $request): JsonResponse
    {
        return success($this->logic->paging($request));
    }

    /**
     * add
     * @param ShopProductSpecAddRequest $request
     * @return JsonResponse
     */
    public function add(ShopProductSpecAddRequest $request): JsonResponse
    {
        if (!is_null($request->productNumber)) {
            $model = ShopProductLogic::findBySerialNumber($request->productNumber);
            if (is_null($model) || $model->user_id !== MAINID) {
                if (config('app.superId') !== USERID) {
                    return fail(433);
                }
            }
        } else if ($this->logic->checkRepeat($model->product_id ?? 0, $request->randProductId, $request->psName)) {
            return failMessage('同产品下规格名不能重复');
        }
        return success($this->logic->add($request));
    }

    /**
     * edit
     * @param ShopProductSpecEditRequest $request
     * @return JsonResponse
     */
    public function edit(ShopProductSpecEditRequest $request): JsonResponse
    {
        $model = $this->logic->findBySerialNumber($request);
        if (is_null($model)) return fail(433);
        else if (config('app.superId') !== USERID) {
            if (USERID === MAINID && $model->user_id !== USERID) return fail(433);
            else if (USERID !== MAINID && !in_array($model->user_id, [USERID, MAINID])) return fail(433);
        } else if ($this->logic->checkRepeat($model->product_id ?? 0, $request->randProductId, $request->psName, $model->ps_id)) {
            return failMessage('同产品下规格名不能重复');
        }
        $this->logic->edit($request, $model);
        return success();
    }

    /**
     * detail
     * @param ShopProductSpecNumberRequest $request
     * @return JsonResponse
     */
    public function detail(ShopProductSpecNumberRequest $request): JsonResponse
    {
        $model = $this->logic->findBySerialNumber($request);
        if (is_null($model) || $model->user_id !== MAINID) return fail(433);
        return success($model);
    }

    /**
     * detail
     * @param ShopProductSpecNumberRequest $request
     * @return JsonResponse
     */
    public function delete(ShopProductSpecNumberRequest $request): JsonResponse
    {
        $model = $this->logic->findBySerialNumber($request);
        if (is_null($model) || $model->ps_is_delete === 1 || $model->user_id !== MAINID) return fail(433);
        $model->ps_is_delete = 1;
        $model->deleted_at = now();
        $model->save();
        OperateLogLogic::add();
        return success($model);
    }

    /**
     * editPrice
     * @param ShopProductSpecEditPriceRequest $request
     * @return JsonResponse
     */
    public function editPrice(ShopProductSpecEditPriceRequest $request): JsonResponse
    {
        if (config('app.superId') !== MAINID) return fail(420);
        $shopProduct = ShopProductLogic::findBySerialNumber($request, 'productId');
        if (is_null($shopProduct)) return fail(422);
        else if (count($request->price) !== $this->logic->countByWhere([
                'psIsDelete' => 2,
                'productId' => $shopProduct->product_id,
                'whereIn' => ['psId', array_keys($request->price)],
            ])) return fail(422);
        foreach ($request->price as $k => $v) {
            $this->logic->updateByWhere([
                'psPrice' => (float)$v['price'] > 0 ? $v['price'] : null,
                'psPriceUnderlined' => (float)$v['marketPrice'] > 0 ? $v['marketPrice'] : 0.01,
            ], 'psId', $k);
        }
        $shopProduct->operated_at = now();
        $shopProduct->save();
        OperateLogLogic::add();
        return success();
    }

    /**
     * editStock
     * @param ShopProductSpecEditStockRequest $request
     * @return JsonResponse
     */
    public function editStock(ShopProductSpecEditStockRequest $request): JsonResponse
    {
        if (config('app.superId') !== MAINID) return fail(420);
        $shopProduct = ShopProductLogic::findBySerialNumber($request, 'productId');
        if (is_null($shopProduct)) return fail(422);
        else if (count($request->stock) !== $this->logic->countByWhere([
                'psIsDelete' => 2,
                'productId' => $shopProduct->product_id,
                'whereIn' => ['psId', array_keys($request->stock)],
            ])) return fail(422);
        foreach ($request->stock as $k => $v) {
            $this->logic->updateByWhere([
                'psUsableStock' => $v,
                'psTotalStock' => bcadd($v, $this->logic->valueByWhere('psId', $k, 'psDisableStock')),
            ], 'psId', $k);
        }
        ShopProductLogic::editStock($shopProduct);
        $shopProduct->operated_at = now();
        $shopProduct->save();
        OperateLogLogic::add();
        return success();
    }
}
